/*
 *
 * Copyright (c) 2025, NexIoT. All Rights Reserved.
 *
 * @Description: 本文件由 gitee.com/NexIoT 开发并拥有版权，未经授权严禁擅自商用、复制或传播。
 * @Author: gitee.com/NexIoT
 * @Email: wo8335224@gmail.com
 * @Wechat: outlookFil
 *
 *
 */

package cn.universal.web;

import static org.junit.jupiter.api.Assertions.*;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpStatus;
import cn.universal.rule.rulego.client.RulegoApiClient;
import cn.universal.rule.rulego.model.RulegoApiResponse;
import cn.universal.rule.rulego.model.RulegoChainInfo;
import cn.universal.rule.rulego.model.RulegoChainListResponse;
import cn.universal.rule.rulego.model.RulegoChainResponse;
import cn.universal.rule.rulego.model.RulegoSaveRequest;
import cn.universal.rule.rulego.model.RulegoSuccessResponse;
import cn.universal.rule.rulego.model.RulegoTriggerRequest;
import cn.universal.rule.rulego.model.RulegoTriggerResponse;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledIfSystemProperty;
import org.springframework.test.util.ReflectionTestUtils;

/**
 * RulegoApiClient 基于Hutool的真实API测试 不启动Spring容器，实际调用RuleGo API
 *
 * <p>运行命令： mvn test -Dtest=RulegoApiClientHutoolTest -Dmaven.test.skip=false -Dhutool.api.test=true
 *
 * @author gitee.com/NexIoT
 * @since 2025/01/15
 */
@EnabledIfSystemProperty(named = "hutool.api.test", matches = "true")
class RulegoApiClientHutoolTest {

  private RulegoApiClient rulegoApiClient;

  // 配置参数 - 可通过系统属性覆盖
  private static final String BASE_URL =
      System.getProperty("rulego.base.url", "http://192.168.31.194:9090");
  private static final String WEB_URL =
      System.getProperty("rulego.web.url", "http://rule.192886.xyz:81/#");
  private static final String TOKEN =
      System.getProperty("rulego.token", "2af255ea5618467d914c67a8beeca31d");
  private static final String TEST_CHAIN_ID = "hutool-test-" + System.currentTimeMillis();

  @BeforeEach
  void setUp() {
    // 手动创建对象，不依赖Spring容器
    rulegoApiClient = new RulegoApiClient();

    // 使用ReflectionTestUtils注入配置值
    ReflectionTestUtils.setField(rulegoApiClient, "baseUrl", BASE_URL);
    ReflectionTestUtils.setField(rulegoApiClient, "webUrl", WEB_URL);
    ReflectionTestUtils.setField(rulegoApiClient, "token", TOKEN);

    System.out.println("=== Hutool API测试配置 ===");
    System.out.println("Base URL: " + BASE_URL);
    System.out.println("Web URL: " + WEB_URL);
    System.out.println("Token: " + TOKEN.substring(0, Math.min(10, TOKEN.length())) + "...");
    System.out.println("Test Chain ID: " + TEST_CHAIN_ID);
    System.out.println("=========================");

    // 检查网络连接
    checkNetworkConnection();
  }

  /** 检查网络连接是否可用 */
  private void checkNetworkConnection() {
    System.out.println("=== 检查网络连接 ===");
    String testUrl = BASE_URL + "/api/v1/rules";

    try {
      System.out.println("测试URL: " + testUrl);

      HttpRequest request = HttpRequest.get(testUrl).header("Content-Type", "application/json");

      if (StrUtil.isNotBlank(TOKEN)) {
        request.header("Authorization", "Bearer " + TOKEN);
      }

      HttpResponse response = request.execute();
      System.out.println("网络连接状态码: " + response.getStatus());
      System.out.println("响应内容长度: " + (response.body() != null ? response.body().length() : 0));

      if (response.getStatus() == HttpStatus.HTTP_OK) {
        System.out.println("✅ 网络连接正常");
      } else {
        System.err.println("⚠️  网络连接异常，状态码: " + response.getStatus());
      }
    } catch (Exception e) {
      System.err.println("❌ 网络连接失败: " + e.getMessage());
      e.printStackTrace();
    }
    System.out.println("=========================");
  }

  @Test
  void testSaveChainInfo() {
    System.out.println("\n=== 测试保存规则链基础信息 ===");

    try {
      // 准备测试数据
      RulegoSaveRequest request = new RulegoSaveRequest();
      request.setId(TEST_CHAIN_ID);
      request.setName("Hutool测试规则链");
      request.setDescription("这是一个基于Hutool测试创建的规则链");
      request.setRoot(false);

      System.out.println("创建规则链ID: " + TEST_CHAIN_ID);
      System.out.println("规则链名称: " + request.getName());
      System.out.println("规则链描述: " + request.getDescription());

      // 调用真实的API
      RulegoApiResponse<RulegoSuccessResponse> response = rulegoApiClient.saveChainInfo(request);

      // 验证响应
      assertNotNull(response, "响应不应为null");
      System.out.println("响应成功: " + response.getSuccess());
      System.out.println("响应消息: " + response.getMessage());

      // 基本验证
      assertTrue(response.getSuccess(), "保存操作应该成功");
      assertNotNull(response.getMessage(), "响应消息不应为null");

      System.out.println("✅ 保存规则链基础信息测试通过");

    } catch (Exception e) {
      System.err.println("❌ API调用失败: " + e.getMessage());
      e.printStackTrace();

      // 跳过测试而不是失败
      org.junit.jupiter.api.Assumptions.assumeTrue(false, "API服务不可用: " + e.getMessage());
    }
  }

  @Test
  void testGetChainList() {
    System.out.println("\n=== 测试获取规则链列表 ===");

    try {
      // 调用真实的API
      RulegoApiResponse<RulegoChainListResponse> response = rulegoApiClient.getChainList();

      // 验证响应
      assertNotNull(response, "响应不应为null");
      System.out.println("响应成功: " + response.getSuccess());
      System.out.println("响应消息: " + response.getMessage());
      System.out.println(
          "规则链数量: "
              + (response.getData() != null && response.getData().getData() != null
                  ? response.getData().getData().size()
                  : 0));

      // 基本验证
      assertTrue(response.getSuccess(), "获取列表应该成功");
      assertNotNull(response.getData(), "规则链列表不应为null");

      // 输出前几个规则链信息
      if (response.getData() != null
          && response.getData().getData() != null
          && !response.getData().getData().isEmpty()) {
        System.out.println("前3个规则链信息:");
        response.getData().getData().stream()
            .limit(3)
            .forEach(
                chain -> System.out.println("  - " + chain.getName() + " (" + chain.getId() + ")"));
      }

      System.out.println("✅ 获取规则链列表测试通过");

    } catch (Exception e) {
      System.err.println("❌ API调用失败: " + e.getMessage());
      e.printStackTrace();

      // 跳过测试而不是失败
      org.junit.jupiter.api.Assumptions.assumeTrue(false, "API服务不可用: " + e.getMessage());
    }
  }

  @Test
  void testGetChainDetail() {
    System.out.println("\n=== 测试获取规则链详情 ===");

    try {
      // 先创建一个规则链
      RulegoSaveRequest createRequest = new RulegoSaveRequest();
      createRequest.setId(TEST_CHAIN_ID);
      createRequest.setName("详情测试规则链");
      createRequest.setDescription("用于获取详情的测试规则链");
      createRequest.setRoot(false);

      rulegoApiClient.saveChainInfo(createRequest);
      System.out.println("已创建测试规则链: " + TEST_CHAIN_ID);

      // 等待一下，确保创建完成
      Thread.sleep(1000);

      // 调用真实的API获取详情
      RulegoApiResponse<RulegoChainInfo> response = rulegoApiClient.getChainDetail(TEST_CHAIN_ID);

      // 验证响应
      assertNotNull(response, "响应不应为null");
      assertTrue(response.getSuccess(), "获取详情应该成功");

      RulegoChainInfo chainInfo = response.getData();
      if (chainInfo != null) {
        System.out.println("规则链ID: " + chainInfo.getId());
        System.out.println("规则链名称: " + chainInfo.getName());
        System.out.println("规则链描述: " + chainInfo.getDescription());
        System.out.println("规则链状态: " + chainInfo.getStatus());
        System.out.println("创建时间: " + chainInfo.getCreateTime());
        System.out.println("更新时间: " + chainInfo.getUpdateTime());
      }

      // 基本验证
      assertEquals(TEST_CHAIN_ID, chainInfo.getId(), "规则链ID应该匹配");

      System.out.println("✅ 获取规则链详情测试通过");

    } catch (Exception e) {
      System.err.println("❌ API调用失败: " + e.getMessage());
      e.printStackTrace();

      // 跳过测试而不是失败
      org.junit.jupiter.api.Assumptions.assumeTrue(false, "API服务不可用: " + e.getMessage());
    }
  }

  @Test
  void testSaveChainDsl() {
    System.out.println("\n=== 测试保存规则链DSL ===");

    try {
      // 先创建一个规则链
      RulegoSaveRequest createRequest = new RulegoSaveRequest();
      createRequest.setId(TEST_CHAIN_ID);
      createRequest.setName("DSL测试规则链");
      createRequest.setDescription("用于DSL测试的规则链");
      createRequest.setRoot(false);

      rulegoApiClient.saveChainInfo(createRequest);
      System.out.println("已创建测试规则链: " + TEST_CHAIN_ID);

      // 等待一下，确保创建完成
      Thread.sleep(1000);

      // 准备DSL数据
      String dsl =
          """
          {
            "nodes": [
              {
                "id": "start",
                "type": "start",
                "name": "开始节点",
                "config": {}
              },
              {
                "id": "log",
                "type": "log",
                "name": "日志节点",
                "config": {
                  "message": "Hutool测试日志"
                }
              },
              {
                "id": "end",
                "type": "end",
                "name": "结束节点",
                "config": {}
              }
            ],
            "edges": [
              {
                "id": "edge1",
                "from": "start",
                "to": "log"
              },
              {
                "id": "edge2",
                "from": "log",
                "to": "end"
              }
            ]
          }
          """;

      System.out.println("保存DSL内容长度: " + dsl.length());

      // 调用真实的API保存DSL
      RulegoApiResponse<RulegoChainResponse> response =
          rulegoApiClient.saveChainDsl(TEST_CHAIN_ID, dsl);

      // 验证响应
      assertNotNull(response, "响应不应为null");
      System.out.println("响应成功: " + response.getSuccess());
      System.out.println("响应消息: " + response.getMessage());

      // 基本验证
      assertTrue(response.getSuccess(), "保存DSL应该成功");
      assertNotNull(response.getMessage(), "响应消息不应为null");

      System.out.println("✅ 保存规则链DSL测试通过");

    } catch (Exception e) {
      System.err.println("❌ API调用失败: " + e.getMessage());
      e.printStackTrace();

      // 跳过测试而不是失败
      org.junit.jupiter.api.Assumptions.assumeTrue(false, "API服务不可用: " + e.getMessage());
    }
  }

  @Test
  void testDeployAndStopChain() {
    System.out.println("\n=== 测试部署和停止规则链 ===");

    try {
      // 先创建一个规则链
      RulegoSaveRequest createRequest = new RulegoSaveRequest();
      createRequest.setId(TEST_CHAIN_ID);
      createRequest.setName("部署测试规则链");
      createRequest.setDescription("用于部署测试的规则链");
      createRequest.setRoot(false);

      rulegoApiClient.saveChainInfo(createRequest);
      System.out.println("已创建测试规则链: " + TEST_CHAIN_ID);

      // 等待一下，确保创建完成
      Thread.sleep(1000);

      // 部署规则链
      System.out.println("开始部署规则链...");
      RulegoApiResponse<RulegoSuccessResponse> deployResponse =
          rulegoApiClient.deployChain(TEST_CHAIN_ID);

      assertNotNull(deployResponse, "部署响应不应为null");
      System.out.println("部署成功: " + deployResponse.getSuccess());
      System.out.println("部署消息: " + deployResponse.getMessage());

      assertTrue(deployResponse.getSuccess(), "部署应该成功");

      // 等待一下，确保部署完成
      Thread.sleep(2000);

      // 停止规则链
      System.out.println("开始停止规则链...");
      RulegoApiResponse<RulegoSuccessResponse> stopResponse =
          rulegoApiClient.stopChain(TEST_CHAIN_ID);

      assertNotNull(stopResponse, "停止响应不应为null");
      System.out.println("停止成功: " + stopResponse.getSuccess());
      System.out.println("停止消息: " + stopResponse.getMessage());

      assertTrue(stopResponse.getSuccess(), "停止应该成功");

      System.out.println("✅ 部署和停止规则链测试通过");

    } catch (Exception e) {
      System.err.println("❌ API调用失败: " + e.getMessage());
      e.printStackTrace();

      // 跳过测试而不是失败
      org.junit.jupiter.api.Assumptions.assumeTrue(false, "API服务不可用: " + e.getMessage());
    }
  }

  @Test
  void testTriggerChain() {
    System.out.println("\n=== 测试触发规则链 ===");

    try {
      // 先创建一个规则链
      RulegoSaveRequest createRequest = new RulegoSaveRequest();
      createRequest.setId(TEST_CHAIN_ID);
      createRequest.setName("触发测试规则链");
      createRequest.setDescription("用于触发测试的规则链");
      createRequest.setRoot(false);

      rulegoApiClient.saveChainInfo(createRequest);
      System.out.println("已创建测试规则链: " + TEST_CHAIN_ID);

      // 等待一下，确保创建完成
      Thread.sleep(1000);

      // 准备触发数据
      RulegoTriggerRequest triggerRequest = new RulegoTriggerRequest();
      triggerRequest.setChainId(TEST_CHAIN_ID);
      triggerRequest.setData(
          "{\"test\": \"Hutool测试数据\", \"timestamp\": " + System.currentTimeMillis() + "}");

      System.out.println("触发数据: " + triggerRequest.getData());

      // 调用真实的API触发规则链
      RulegoApiResponse<RulegoTriggerResponse> response =
          rulegoApiClient.triggerChainSync(triggerRequest);

      // 验证响应
      assertNotNull(response, "响应不应为null");
      System.out.println("响应成功: " + response.getSuccess());
      System.out.println("响应消息: " + response.getMessage());
      System.out.println(
          "执行ID: " + (response.getData() != null ? response.getData().getExecutionId() : "null"));

      // 基本验证
      assertTrue(response.getSuccess(), "触发应该成功");
      assertNotNull(response.getMessage(), "响应消息不应为null");

      System.out.println("✅ 触发规则链测试通过");

    } catch (Exception e) {
      System.err.println("❌ API调用失败: " + e.getMessage());
      e.printStackTrace();

      // 跳过测试而不是失败
      org.junit.jupiter.api.Assumptions.assumeTrue(false, "API服务不可用: " + e.getMessage());
    }
  }

  @Test
  void testDeleteChain() {
    System.out.println("\n=== 测试删除规则链 ===");

    try {
      // 先创建一个规则链
      RulegoSaveRequest createRequest = new RulegoSaveRequest();
      createRequest.setId(TEST_CHAIN_ID);
      createRequest.setName("删除测试规则链");
      createRequest.setDescription("用于删除测试的规则链");
      createRequest.setRoot(false);

      rulegoApiClient.saveChainInfo(createRequest);
      System.out.println("已创建测试规则链: " + TEST_CHAIN_ID);

      // 等待一下，确保创建完成
      Thread.sleep(1000);

      // 调用真实的API删除规则链
      RulegoApiResponse<RulegoSuccessResponse> response =
          rulegoApiClient.deleteChain(TEST_CHAIN_ID);

      // 验证响应
      assertNotNull(response, "响应不应为null");
      System.out.println("响应成功: " + response.getSuccess());
      System.out.println("响应消息: " + response.getMessage());

      // 基本验证
      assertTrue(response.getSuccess(), "删除应该成功");
      assertNotNull(response.getMessage(), "响应消息不应为null");

      System.out.println("✅ 删除规则链测试通过");

    } catch (Exception e) {
      System.err.println("❌ API调用失败: " + e.getMessage());
      e.printStackTrace();

      // 跳过测试而不是失败
      org.junit.jupiter.api.Assumptions.assumeTrue(false, "API服务不可用: " + e.getMessage());
    }
  }

  @Test
  void testConfigurationInfo() {
    System.out.println("\n=== 测试配置信息 ===");

    try {
      System.out.println("Base URL: " + BASE_URL);
      System.out.println("Web URL: " + WEB_URL);
      System.out.println("Token: " + TOKEN.substring(0, Math.min(10, TOKEN.length())) + "...");
      System.out.println("Test Chain ID: " + TEST_CHAIN_ID);

      // 验证配置不为空
      assertNotNull(BASE_URL, "Base URL不应为null");
      assertNotNull(WEB_URL, "Web URL不应为null");
      assertNotNull(TOKEN, "Token不应为null");
      assertNotNull(TEST_CHAIN_ID, "Test Chain ID不应为null");

      // 验证URL格式
      assertTrue(BASE_URL.startsWith("http"), "Base URL应该以http开头");
      assertTrue(WEB_URL.startsWith("http"), "Web URL应该以http开头");

      System.out.println("✅ 配置信息测试通过");

    } catch (Exception e) {
      System.err.println("❌ 配置信息测试失败: " + e.getMessage());
      e.printStackTrace();

      // 跳过测试而不是失败
      org.junit.jupiter.api.Assumptions.assumeTrue(false, "配置信息测试失败: " + e.getMessage());
    }
  }

  @Test
  void testFullWorkflow() {
    System.out.println("\n=== 测试完整工作流程 ===");

    try {
      // 1. 创建规则链
      System.out.println("1. 创建规则链...");
      RulegoSaveRequest createRequest = new RulegoSaveRequest();
      createRequest.setId(TEST_CHAIN_ID);
      createRequest.setName("完整流程测试规则链");
      createRequest.setDescription("用于完整流程测试的规则链");
      createRequest.setRoot(false);

      RulegoApiResponse<RulegoSuccessResponse> createResponse =
          rulegoApiClient.saveChainInfo(createRequest);
      assertTrue(createResponse.getSuccess(), "创建规则链应该成功");
      System.out.println("✅ 创建规则链成功");

      // 等待一下
      Thread.sleep(1000);

      // 2. 获取规则链列表
      System.out.println("2. 获取规则链列表...");
      RulegoApiResponse<RulegoChainListResponse> listResponse = rulegoApiClient.getChainList();
      assertTrue(listResponse.getSuccess(), "获取列表应该成功");
      System.out.println(
          "✅ 获取规则链列表成功，数量: "
              + (listResponse.getData() != null && listResponse.getData().getData() != null
                  ? listResponse.getData().getData().size()
                  : 0));

      // 3. 获取规则链详情
      System.out.println("3. 获取规则链详情...");
      RulegoApiResponse<RulegoChainInfo> detailResponse =
          rulegoApiClient.getChainDetail(TEST_CHAIN_ID);
      assertTrue(detailResponse.getSuccess(), "获取详情应该成功");
      System.out.println("✅ 获取规则链详情成功");
      if (detailResponse.getData() != null) {
        System.out.println("  - ID: " + detailResponse.getData().getId());
        System.out.println("  - 名称: " + detailResponse.getData().getName());
        System.out.println("  - 状态: " + detailResponse.getData().getStatus());
      }

      // 4. 保存DSL
      System.out.println("4. 保存DSL...");
      String dsl =
          "{\"nodes\":[{\"id\":\"start\",\"type\":\"start\",\"name\":\"开始节点\"}],\"edges\":[]}";
      RulegoApiResponse<RulegoChainResponse> dslResponse =
          rulegoApiClient.saveChainDsl(TEST_CHAIN_ID, dsl);
      assertTrue(dslResponse.getSuccess(), "保存DSL应该成功");
      System.out.println("✅ 保存DSL成功");

      // 等待一下
      Thread.sleep(1000);

      // 5. 部署规则链
      System.out.println("5. 部署规则链...");
      RulegoApiResponse<RulegoSuccessResponse> deployResponse =
          rulegoApiClient.deployChain(TEST_CHAIN_ID);

      // 输出详细的部署响应信息
      System.out.println("部署响应详情:");
      System.out.println("  - 成功状态: " + deployResponse.getSuccess());
      System.out.println("  - 响应消息: " + deployResponse.getMessage());

      assertTrue(deployResponse.getSuccess(), "部署应该成功");
      System.out.println("✅ 部署规则链成功");

      // 等待一下
      Thread.sleep(2000);

      // 6. 触发规则链
      System.out.println("6. 触发规则链...");
      RulegoTriggerRequest triggerRequest = new RulegoTriggerRequest();
      triggerRequest.setChainId(TEST_CHAIN_ID);
      triggerRequest.setData("{\"test\": \"完整流程测试\"}");

      RulegoApiResponse<RulegoTriggerResponse> triggerResponse =
          rulegoApiClient.triggerChainSync(triggerRequest);
      assertTrue(triggerResponse.getSuccess(), "触发应该成功");
      System.out.println("✅ 触发规则链成功");

      // 等待一下
      Thread.sleep(1000);

      // 7. 停止规则链
      System.out.println("7. 停止规则链...");
      RulegoApiResponse<RulegoSuccessResponse> stopResponse =
          rulegoApiClient.stopChain(TEST_CHAIN_ID);
      assertTrue(stopResponse.getSuccess(), "停止应该成功");
      System.out.println("✅ 停止规则链成功");

      // 等待一下
      Thread.sleep(1000);

      // 8. 删除规则链
      System.out.println("8. 删除规则链...");
      RulegoApiResponse<RulegoSuccessResponse> deleteResponse =
          rulegoApiClient.deleteChain(TEST_CHAIN_ID);
      assertTrue(deleteResponse.getSuccess(), "删除应该成功");
      System.out.println("✅ 删除规则链成功");

      System.out.println("✅ 完整工作流程测试通过");

    } catch (Exception e) {
      System.err.println("❌ 完整工作流程测试失败: " + e.getMessage());
      e.printStackTrace();

      // 跳过测试而不是失败
      org.junit.jupiter.api.Assumptions.assumeTrue(false, "完整工作流程测试失败: " + e.getMessage());
    }
  }
}
